from PyQt4 import QtGui, QtCore
from socketbase import SocketBase
from qpyshare_core import QPyShare_Core
from qpyshare_share import QPyShare_Share
from mainwindow import Ui_MainWindow

class QPyShare_UI(QtGui.QMainWindow):
    
    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self,parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.lblStatus = QtGui.QLabel(QtCore.QCoreApplication.translate("QPyShare_UI","Current Connection : None"))
        self.ui.txtCurrentConnection.setText(self.lblStatus.text())
        self.ui.statusbar.addPermanentWidget(self.lblStatus)
        
        self.ui.treeWidget.setItemDelegate(ProgressBarItemDelegate(self))
        self.ui.treeWidget.setColumnHidden(0,True)
        self.ui.treeWidget.setColumnWidth(1,220)
        
        self.core = QPyShare_Core()
        
        self.title = self.core.title + " - UI"
        self.popupTitle = self.title + " - Info"
        
        self.setWindowTitle(self.title)
        
        self.connect(self.core , QtCore.SIGNAL("log(QString)"), self.log)
        self.connect(self.core, QtCore.SIGNAL("stateChanged()"), self.stateChanged)
        self.connect(self.core, QtCore.SIGNAL("newChatMessage(QString)"), self.addToChat)
        
        self.connect(self.core.shareList, QtCore.SIGNAL("shareUpdated(PyQt_PyObject)"), self.updateList)
        self.connect(self.core.shareList, QtCore.SIGNAL("shareStateUpdated(PyQt_PyObject)"), self.shareStateUpdated)
        self.connect(self.core.shareList, QtCore.SIGNAL("shareFinished(PyQt_PyObject)"), self.shareFinished)
        
        self.connect(self.core.shareList, QtCore.SIGNAL("shareDeleted(QString)"), self.updateList_shareDeleted)
        
        self.connect(self.core.shareList, QtCore.SIGNAL("messageMD5(QString)"), self.messageMD5)
        self.connect(self.core.shareList, QtCore.SIGNAL("messageMD5Close()"), self.messageMD5Close)
        self.connect(self.core.shareList, QtCore.SIGNAL("messageWarning(QString)"), self.messageWarning)
        
        self.connect(self.ui.btnAddFile, QtCore.SIGNAL("clicked()"), self.slot_addFile)
        self.connect(self.ui.btnSendFile, QtCore.SIGNAL("clicked()"), self.slot_sendFile)
        self.connect(self.ui.btnResumeFile, QtCore.SIGNAL("clicked()"), self.slot_resumeFile)
        self.connect(self.ui.btnPauseFile, QtCore.SIGNAL("clicked()"), self.slot_pauseFile)
        self.connect(self.ui.btnOpenFile, QtCore.SIGNAL("clicked()"), self.slot_openRunFile)
        
        self.connect(self.ui.btnServer, QtCore.SIGNAL("clicked()"), self.slot_serverMode)
        self.connect(self.ui.btnDisconnect, QtCore.SIGNAL("clicked()"), self.core.disconnectSocket)
        self.connect(self.ui.btnStopServer, QtCore.SIGNAL("clicked()"), self.core.stopServer)
        self.connect(self.ui.btnClient, QtCore.SIGNAL("clicked()"), self.slot_clientMode)
        
        self.connect(self.ui.txtChatInput, QtCore.SIGNAL("returnPressed()"), self.sendChat)
        
        self.connect(self.ui.treeWidget,QtCore.SIGNAL('itemClicked(QTreeWidgetItem *, int)'), self.showShareInfo)
        self.connect(self.ui.treeWidget,QtCore.SIGNAL('itemSelectionChanged()'), self.treeWidget_selectionChanged)
        
        self.connect(QtCore.QCoreApplication.instance(), QtCore.SIGNAL("aboutToQuit()"), self.aboutToQuit)
        #md5 progress bar
        self.progressdialog = QtGui.QProgressDialog(self)
        self.progressdialog.setAutoClose(False)
        self.progressdialog.setRange(0,0)
        
        #tray icon
        self.trayMenu = QtGui.QMenu(self.core.title, self)
        self.actionShowHide = self.trayMenu.addAction(QtCore.QCoreApplication.translate("QPyShare_UI","Hide Window"))
        self.actionQuit = self.trayMenu.addAction(QtCore.QCoreApplication.translate("QPyShare_UI","Quit"))
        
        self.connect(self.actionQuit, QtCore.SIGNAL("triggered()"), QtCore.QCoreApplication.instance().quit)
        self.connect(self.actionShowHide, QtCore.SIGNAL("triggered()"), self.showHide)
        
        self.trayIcon = QtGui.QSystemTrayIcon(QtGui.QIcon(":/images/tab_logs.png"),self)
        self.trayIcon.setToolTip(self.core.title)
        self.trayIcon.setContextMenu(self.trayMenu)
        self.connect(self.trayIcon, QtCore.SIGNAL("activated( QSystemTrayIcon::ActivationReason )"), self.trayIconClicked)
       
        self.trayIcon.show()
        
        self.setIconEnabled(False)
   
    #Tray icon actions
    
    def setIconEnabled(self, bool):
        size = self.trayIcon.geometry().size()
        icon = QtGui.QIcon(":/images/tab_logs.png")
        if bool:
            state = QtGui.QIcon.Normal
        else:
            state = QtGui.QIcon.Disabled
        icon2 = icon.pixmap(size, state, QtGui.QIcon.Off)
        self.trayIcon.setIcon(QtGui.QIcon(icon2))

    def showHide(self):
        self.setVisible(not self.isVisible())
        if self.isVisible():
            self.actionShowHide.setText(QtCore.QCoreApplication.translate("QPyShare_UI","Hide Window"))
        else:
            self.actionShowHide.setText(QtCore.QCoreApplication.translate("QPyShare_UI","Show Window"))
            
    def trayIconClicked(self, reason):
        if reason == QtGui.QSystemTrayIcon.DoubleClick:
            self.showHide()
    #------- Share info and status
    
    def treeWidget_selectionChanged(self):
        lista = self.ui.treeWidget.selectedItems()
        if len(lista) > 0:
            item = lista[0]
            self.showShareInfo(item,0)

    def shareStateUpdated(self,share):
        lista = self.ui.treeWidget.selectedItems()
        if len(lista) > 0:
            if lista[0].text(0) == share.id:
                self.updateButtonStatus(share)
    
    def shareFinished(self,share):
        self.trayIcon.showMessage(self.title,QtCore.QCoreApplication.translate("QPyShare_UI","%1 finished").arg(share.filename))
        
    def showShareInfo(self, item, int):
        
        share = self.core.shareList.share_list[str(item.text(0))]
        shareInfo = self.ui.txtShareInfo
        shareInfo.clear()
        cursor = QtGui.QTextCursor(shareInfo.document())

        if share.previewType == QPyShare_Share.preview_Image:
            
            image = QtGui.QImage()
            image.loadFromData(share.preview,"JPG")
            shareInfo.document().addResource(QtGui.QTextDocument.ImageResource, QtCore.QUrl("previewIMG"), QtCore.QVariant(image))
            cursor.insertImage("previewIMG")
            
        elif share.previewType == QPyShare_Share.preview_Text:
            cursor.insertText(QtCore.QString(share.preview))
            
        elif share.previewType == QPyShare_Share.preview_None:
            cursor.insertText(QtCore.QCoreApplication.translate("QPyShare_UI","No info available for this share"))
            
        self.updateButtonStatus(share)

    def updateList(self,share):
        
        lista = self.ui.treeWidget.findItems(share.id,QtCore.Qt.MatchExactly,0)
        if len(lista) == 0:
            #Create item
            a = QtGui.QTreeWidgetItem()
            self.ui.treeWidget.addTopLevelItem(a)
            
            a.setText(0,share.id)
            a.setText(1,share.filename)
            
            if share.previewType == QPyShare_Share.preview_Image:
                path_icon = ":/images/icon_image.png"
            elif share.previewType == QPyShare_Share.preview_Text:
                path_icon = ":/images/icon_text.png"
            else:
                path_icon = ":/images/icon_file.png"
            
            a.setIcon(1,QtGui.QIcon(path_icon))
            a.setText(2,share.sizeToText())
            
            if share.mode == QPyShare_Share.mode_Upload:
                path = ":/images/mode_upload.png"
            else:
                path = ":/images/mode_download.png"
            a.setIcon(3,QtGui.QIcon(path))
            
            a.setText(4,"0")
        
        else:
            #Update item
            a = lista[0]
            
        a.setText(3,str(share.transferred/1024) + " Kb")
        a.setText(4,share.transferredPercentToText())
        a.setText(5,share.statusToText())
        a.setText(6,share.speedToText())
    
    def updateList_shareDeleted(self,share_id):
        lista = self.ui.treeWidget.findItems(share_id,QtCore.Qt.MatchExactly,0)
        if( len(lista) == 1):
            item = lista[0]
            index = self.ui.treeWidget.indexOfTopLevelItem(item)
            self.ui.treeWidget.takeTopLevelItem(index)

    #------- Showing messages
    def messageMD5(self, msg):
        self.progressdialog.setLabelText(QtCore.QCoreApplication.translate("QPyShare_UI","Generating MD5 ID of %1").arg(msg))
        self.progressdialog.setValue(1)
        
    def messageMD5Close(self):
        self.progressdialog.reset()
        self.progressdialog.cancel()
        
    def messageWarning(self,msg):
        QtGui.QMessageBox.warning(self,self.popupTitle,msg)

    #------------- Chat
    
    def sendChat(self):
        txt = self.ui.txtChatInput.text()
        if self.core.sendChat(txt):
            self.ui.txtChat.append(QtCore.QDateTime.currentDateTime().toString("(dd/MM/yy hh:mm:ss)") + " :: " + QtCore.QCoreApplication.translate("QPyShare_UI","Me: %1").arg(txt))
            self.ui.txtChatInput.clear()
        else:
            self.ui.txtChat.append(QtCore.QDateTime.currentDateTime().toString("(dd/MM/yy hh:mm:ss)") + " :: " + QtCore.QCoreApplication.translate("QPyShare_UI","Can't send message: Disconnected"))
        
    def addToChat(self,msg):
        self.ui.txtChat.append(QtCore.QDateTime.currentDateTime().toString("(dd/MM/yy hh:mm:ss)") + " :: " + QtCore.QCoreApplication.translate("QPyShare_UI","Peer: %1").arg(msg))


    #--------------- Connection button slots
    
    def slot_serverMode(self):
        self.core.start(0,"0.0.0.0",int(self.ui.spnPort.value()))
            
    def slot_clientMode(self):
        self.core.start(1,str(self.ui.txtIP.text()),int(self.ui.spnPort.value()))
        
    #---------------Share buttons slots
    
    def slot_resumeFile(self):
        lista = self.ui.treeWidget.selectedItems()
        if len(lista) > 0:
            id = str(lista[0].text(0))
            self.core.shareList.cmd_send_ResumeShare(id)
            
    def slot_pauseFile(self):
        lista = self.ui.treeWidget.selectedItems()
        if len(lista) > 0:
            id = str(lista[0].text(0))
            self.core.shareList.cmd_send_PauseShare(id)
    
    def slot_openRunFile(self):
        lista = self.ui.treeWidget.selectedItems()
        if len(lista) == 1:
            item = lista[0]
            share = self.core.shareList.share_list[str(item.text(0))]
            if share.canOpenRun():
                QtGui.QDesktopServices.openUrl(QtCore.QUrl(share.fullFilename))
                
    def slot_addFile(self):
        if self.core.isConnectedHSOK():
            filelist = QtGui.QFileDialog.getOpenFileNames(self,"a","b")
            for file in list(filelist):
                self.core.addFilePending(file)
        else:
            QtGui.QMessageBox.warning(self,self.popupTitle,QtCore.QCoreApplication.translate("QPyShare_UI","Can't add files while not connected"))

    def slot_sendFile(self):
        lista = self.ui.treeWidget.selectedItems()
        
        if len(lista) > 0:
            item = lista[0]
            id = item.text(0)
            self.core.shareList.startFT(str(id))

    #---------- Share buttons status
    
    def resetButtonStatus(self):
        self.ui.btnSendFile.setEnabled(False)
        self.ui.btnPauseFile.setEnabled(False)
        self.ui.btnResumeFile.setEnabled(False)
        self.ui.btnOpenFile.setEnabled(False)
        
    def updateButtonStatus(self,share):
        self.ui.btnSendFile.setEnabled(share.canStartSend())
        self.ui.btnPauseFile.setEnabled(share.canPause())
        self.ui.btnResumeFile.setEnabled(share.canResume())
        self.ui.btnOpenFile.setEnabled(share.canOpenRun())
        
    #---------- Connection status
    
    def activateConnectionControls(self,bool):
        self.ui.txtIP.setEnabled(bool)
        self.ui.spnPort.setEnabled(bool)
        self.ui.btnServer.setEnabled(bool)
        self.ui.btnClient.setEnabled(bool)
        self.ui.lblIP.setEnabled(bool)
        self.ui.lblPort.setEnabled(bool)
        
    def stateChanged(self):
        mode = self.core.socket.mode
        state = self.core.state
        
        if mode == SocketBase.modeServer:
            msg = QtCore.QCoreApplication.translate("QPyShare_UI","Server :: ")
        else:
            msg = QtCore.QCoreApplication.translate("QPyShare_UI","Client :: ")
        
        if state == QPyShare_Core.state_Disconnected:
            msg = msg + QtCore.QCoreApplication.translate("QPyShare_UI","Disconnected")
            self.activateConnectionControls(True)
            self.ui.btnDisconnect.setEnabled(False)
            self.ui.btnStopServer.setEnabled(False)
            self.resetButtonStatus()
            self.setIconEnabled(False)
        elif state == QPyShare_Core.state_Connecting:
            self.activateConnectionControls(False)
            if mode == SocketBase.modeServer:
                msg = msg + QtCore.QCoreApplication.translate("QPyShare_UI","Listening")
                self.ui.btnStopServer.setEnabled(True)
                self.ui.btnDisconnect.setEnabled(False)
                self.resetButtonStatus()
            else:
                msg = msg + QtCore.QCoreApplication.translate("QPyShare_UI","Connecting to ...") + self.core.socket.getRemoteInfo()
                self.ui.btnStopServer.setEnabled(False)
                self.ui.btnDisconnect.setEnabled(True)
                self.resetButtonStatus()
            self.setIconEnabled(False)
        elif state == QPyShare_Core.state_Connected:
            msg = msg + QtCore.QCoreApplication.translate("QPyShare_UI","Connected to ") + self.core.socket.getRemoteInfo() 
            self.activateConnectionControls(False)
            self.ui.btnStopServer.setEnabled((mode == SocketBase.modeServer))
            self.ui.btnDisconnect.setEnabled(True)
            self.setIconEnabled(True)
        elif state == QPyShare_Core.state_Connected_HS_OK:
            msg = msg + QtCore.QCoreApplication.translate("QPyShare_UI","Connected and HandShake OK to %1 - QPyShare Remote Version: %2").arg(self.core.socket.getRemoteInfo(),self.core.qpyshare_remote_ver)
            
            self.activateConnectionControls(False)
            self.ui.btnStopServer.setEnabled((mode == SocketBase.modeServer))
            self.ui.btnDisconnect.setEnabled(True)
        
        self.lblStatus.setText(msg)
        self.ui.txtCurrentConnection.setText(msg)
        
        
    #-------------LOGGING
    def log(self, msg):
        self.ui.txtLog.append(msg)
        
        
    # QUIT
    def aboutToQuit(self):
        self.core.disconnectSocket()

class ProgressBarItemDelegate(QtGui.QItemDelegate):
    def __init__(self, parent = None):
        QtGui.QItemDelegate.__init__(self,parent)
        
    def paint(self,painter,option,index):
        if index.column() == 4:
            
            progress = index.data().toInt()[0]
            
            opt = QtGui.QStyleOptionProgressBar()
            opt.rect = option.rect
            opt.minimum = 0
            opt.maximum = 100
            opt.progress = progress
            opt.text = str(progress) + " %"
            opt.textVisible = True
            
            #QtGui.QStyleFactory.create("qtcurve")
            QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_ProgressBar , opt, painter, None)
            
        else:
            QtGui.QItemDelegate.paint(self,painter,option,index)